//
// Copyright (c) MiTAC Corp. All rights reserved.
//------------------------------------------------------------------------------
//
//  File:  Testmenu.c
//  Programmer: Visual.Wei
//  Date: 2007-4-16
//
#include <windows.h>
#include <eboot.h>
#include <oal_blmenu.h>
#ifndef EBOOT_NO_LCD
#include <pagemenu.h>
#endif
#include <ipl_core.h>

extern void *InitDisplay(void);

extern void _OUTUPLLCON(UINT32);
extern void _OUTREG32_delay(void *,UINT32);
extern void _delay(UINT32 val);
VOID OEMInitDebugSerial() ;
void MMU_SetFastBusMode(void);
void MMU_SetAsyncBusMode(void);

static void MemoryTest(OAL_BLMENU_ITEM *pMenu)
{
	UINT32 * bank6base,i;
	bank6base = (UINT32*)OALPAtoVA(0x30090000, FALSE);

	OALMSG(1,(TEXT(" Memory Write\r\n")));
	for(i=0;i<0x100000;i++)
	{
		OUTREG32(bank6base+i, 0x5A5A5A5A);
	}

	OALMSG(1,(TEXT(" Memory Read\r\n")));
	for(i=0;i<0x100000;i++)
	{
		if(INREG32(bank6base+i)!=0x5A5A5A5A)
		{
			OALMSG(1,(TEXT(" Memory Error:0x%x"),bank6base+i));
			return;
		}
	}
	OALMSG(1,(TEXT(" Memory Works Fine\r\n")));
}

static void PowerdownTest(OAL_BLMENU_ITEM * pMenu)
{
	S3C2443_CLKPWR_REG *pCLKPWR = (S3C2443_CLKPWR_REG*)OALPAtoVA(S3C2443_BASE_REG_PA_CLOCK_POWER, FALSE);

	OALMSG(1,(TEXT(" Enter Sleep[Stop]\r\n")));
	OUTREG32(&pCLKPWR->PWRMODE,0x10000);
	OALMSG(1,(TEXT(" Wake up from Sleep\r\n")));
}

static void PowerReset(OAL_BLMENU_ITEM * pMenu)
{
	S3C2443_CLKPWR_REG *pCLKPWR = (S3C2443_CLKPWR_REG*)OALPAtoVA(S3C2443_BASE_REG_PA_CLOCK_POWER, FALSE);


	OUTREG32(&pCLKPWR->RSTCON,0xFF<<8);
	OUTREG32(&pCLKPWR->SWRST,0x533C2443);

}

static void PoweroffTest(OAL_BLMENU_ITEM * pMenu)
{
	S3C2443_IOPORT_REG *pIOPortReg = (S3C2443_IOPORT_REG*)OALPAtoVA(S3C2443_BASE_REG_PA_IOPORT, FALSE);

	//notify CPLD to shutdown all the system
	//notification PIN: GPF1,output
	OALMSG(1,(TEXT(" power off +\r\n")));
	CLRREG32(&pIOPortReg->GPFCON, (3 << 2*1));
	SETREG32(&pIOPortReg->GPFCON, (1 << 2*1));
	//disable pull-up/down resistor
	SETREG32(&pIOPortReg->GPFUDP, (3 << 2*1));

	if(INREG32(&pIOPortReg->GPFDAT)&(1 << 1))
		CLRREG32(&pIOPortReg->GPFDAT, (1 << 1));
	else
		SETREG32(&pIOPortReg->GPFDAT, (1 << 1));
	OALMSG(1,(TEXT(" power off -\r\n")));
}

#if 1

BOOL TWait(DWORD us)
{
	volatile  register DWORD time=0;
	
	while(time<us)
	{
		time++;
	};

	return FALSE;
}
#endif
static void WlanLedShow(OAL_BLMENU_ITEM *pMenu)
{
#define RICHTEK
#define PULSE(width) \
		CLRREG32(&pIOPortReg->GPLDAT, (1 << 4));\
		TWait(width);\
		SETREG32(&pIOPortReg->GPLDAT, (1 << 4));\
		TWait(0x4FF);
	//TOUT0
	S3C2443_PWM_REG *PWM;
	S3C2443_IOPORT_REG *pIOPortReg;
	const UINT16 brightness[11]={0xfE, 0xe7, 0xd0, 0xb9, 0xa2, 0x8b, 0x73, 0x5c, 0x45, 0x2F, 0x24};
	static UINT16 index=0;
	int i;
	
	pIOPortReg = (S3C2443_IOPORT_REG*)OALPAtoVA(S3C2443_BASE_REG_PA_IOPORT, FALSE);	
	PWM = (S3C2443_PWM_REG*)OALPAtoVA(S3C2443_BASE_REG_PA_PWM, FALSE);

	//GPB0
	//SETREG32(&pIOPortReg->GPBUDP, (1 << 0));
#if 1
#ifndef RICHTEK
	//use gpio way
	CLRREG32(&pIOPortReg->GPBCON, 3 << (0*2));
	SETREG32(&pIOPortReg->GPBCON, 1 << (0*2));
	if(INREG32(&pIOPortReg->GPBDAT)&(1 << 0))
		CLRREG32(&pIOPortReg->GPBDAT, (1 << 0));
	else
		SETREG32(&pIOPortReg->GPBDAT, (1 << 0));
#else
	//GPL4,output for RichTek test
	SETREG32(&pIOPortReg->GPLUDP, (3 << (4*2)));
	CLRREG32(&pIOPortReg->GPLCON, 3 << (4*2));
	SETREG32(&pIOPortReg->GPLCON, 1 << (4*2));
	++index;
	if(index<16)
	{
		PULSE(0x9FFF);
		for(i=0;i<index;i++)
		{
			PULSE(0x2F);
		}
		//OALMSG(1,(TEXT("BKL adjust %d\r\n"),index));
	}
	else
	{
		index=0;
		//PULSE(0x4FFFF);
		//shutdown IC
		CLRREG32(&pIOPortReg->GPLDAT, (1 << 4));
	}
#endif

#else	
	CLRREG32(&pIOPortReg->GPBCON, 3 << (0*2));
	SETREG32(&pIOPortReg->GPBCON, 2 << (0*2));

	index++;
	if(index>10)
		index=0;
	OALMSG(1,(TEXT("Brightness: %u\r\n"),brightness[index]));

		//prescaler value=99+1
		CLRREG32(&PWM->TCFG0,0xFF);
		SETREG32(&PWM->TCFG0,99);
		//MUX0 is 1/2
		CLRREG32(&PWM->TCFG1,0xF);
		//--SETREG32(&PWM->TCFG1,0x3);
		//PWM output
		OUTREG32(&PWM->TCNTB0 , 0xFf);
		OUTREG32(&PWM->TCMPB0 ,brightness[index]);
		//config TCON for PWM timer0(update,reload,enable)
		CLRREG32(&PWM->TCON,0xF<<(0*8));
		SETREG32(&PWM->TCON,0x2<<(0*8));
		CLRREG32(&PWM->TCON,0xF<<(0*8));
		SETREG32(&PWM->TCON,0x9<<(0*8));

#endif	

}

static void earphone_isr()
{
	RETAILMSG (1, (TEXT(">>>earphone insert \r\n")));
	IPLIntrDoneIrq(IRQ_EINT18);
}

static void af_bt_isr()
{
	RETAILMSG (1, (TEXT(">>>down pressed \r\n")));
	IPLIntrDoneIrq(IRQ_EINT12);
}

static VOID HeadSetEnable(OAL_BLMENU_ITEM *pMenu)
{
	S3C2443_IOPORT_REG *pIOPortReg;
	UINT32 isledon;
	// Configure GPG10,EINT18
	pIOPortReg = (S3C2443_IOPORT_REG*)OALPAtoVA(S3C2443_BASE_REG_PA_IOPORT, FALSE);

	// set as input
	CLRREG32(&pIOPortReg->GPGCON, (3 << 2*10));
	SETREG32(&pIOPortReg->GPGCON, (2 << 2*10));
	
	//disable pull-up/down resistor
	SETREG32(&pIOPortReg->GPGUDP, (3 << 2*10));
	//edge triggered
	SETREG32(&pIOPortReg->EXTINT2, (0xF << 4*2));

	IPLIntrRequestIrq(IRQ_EINT18,earphone_isr);
	IPLIntrEnableIrq(IRQ_EINT18);
	
	isledon=INREG32(&pIOPortReg->GPGDAT);
	if(isledon& (1 << 10))
		OALMSG(1,(TEXT(" HT high\r\n")));
	else
		OALMSG(1,(TEXT(" HT low\r\n")));

	//keypad interrupt enable
	IPLIntrRequestIrq(IRQ_EINT12,af_bt_isr);
	IPLIntrEnableIrq(IRQ_EINT12);
}

static VOID ClockShow(OAL_BLMENU_ITEM *pMenu)
{
	OALMSG(1,(TEXT(" FCLK: %dMHz\r\n"),IPLGetFclk()/1000000));
	OALMSG(1,(TEXT(" HCLK: %dMHz\r\n"),IPLGetHclk()/1000000));
	OALMSG(1,(TEXT(" PCLK: %dMHz\r\n"),IPLGetPclk()/1000000));
}

static DWORD BCD2DWROD(DWORD val)
{
	return ((val&0xF0)>>4)*10+(val&0xF);
}

static void ResetRTC(OAL_BLMENU_ITEM *pMenu)
{
	S3C2443_RTC_REG * pRTCReg;

	pRTCReg=(S3C2443_RTC_REG *)OALPAtoVA(S3C2443_BASE_REG_PA_RTC, FALSE);

	SETREG32(&pRTCReg->RTCCON, 1);
	
	OUTREG8(&pRTCReg->BCDSEC,0);
	OUTREG8(&pRTCReg->BCDMIN,1);
	OUTREG8(&pRTCReg->BCDHOUR,1);
	OUTREG8(&pRTCReg->BCDDATE,1);
	OUTREG8(&pRTCReg->BCDDAY,1);
	OUTREG8(&pRTCReg->BCDMON,1);
	OUTREG8(&pRTCReg->BCDYEAR,1);
	
	CLRREG32(&pRTCReg->RTCCON, 1);

}

static void ShowRTC(OAL_BLMENU_ITEM *pMenu)
{
	S3C2443_RTC_REG * pRTCReg;
	UINT32 sec,min,hr; 
	UINT32 date,week,mon,year;
	pRTCReg=(S3C2443_RTC_REG *)OALPAtoVA(S3C2443_BASE_REG_PA_RTC, FALSE);

	sec=BCD2DWROD(INREG8(&pRTCReg->BCDSEC)&0x7F);
	min=BCD2DWROD(INREG8(&pRTCReg->BCDMIN)&0x7F);
	hr=BCD2DWROD(INREG8(&pRTCReg->BCDHOUR)&0x3f);
	date=BCD2DWROD(INREG8(&pRTCReg->BCDDATE));
	week=BCD2DWROD(INREG8(&pRTCReg->BCDDAY)&0x3F);
	mon=BCD2DWROD(INREG8(&pRTCReg->BCDMON)&0x1F);
	year=BCD2DWROD(INREG8(&pRTCReg->BCDYEAR));

	OALMSG(1,(TEXT(" %d-%d-%d\r\n"),year,mon,date));
	OALMSG(1,(TEXT(" %d:%d:%d\r\n"),hr,min,sec));
}
OAL_BLMENU_ITEM g_menuTest[] = {	 
                                          {
                                              L'1', L"backlight", WlanLedShow,
                                              NULL, NULL, NULL
                                          },         
                                          {
                                              L'2', L"Power Down", PowerdownTest,
                                              NULL, NULL, NULL
                                          },         
                                          {
                                              L'3', L"Power Off", PoweroffTest,
                                              NULL, NULL, NULL
                                          },   
                                          {
                                              L'4', L"Software Reset", PowerReset,
                                              NULL, NULL, NULL
                                          },                                             
                                          {
                                              L'5', L"Detect Head Set", HeadSetEnable,
                                              NULL, NULL, NULL
                                          },
                                          {
                                              L'6', L"Memory Test", MemoryTest,
                                              NULL, NULL, NULL
                                          },         
                                          {
                                              L'7', L"Show clock freq.", ClockShow,
                                              NULL, NULL, NULL
                                          },             
                                                                                    {
                                              L'8', L"Reset RTC", ResetRTC,
                                              NULL, NULL, NULL
                                          },  
                                          {
                                              L'9', L"Show RTC", ShowRTC,
                                              NULL, NULL, NULL
                                          },      
                                          {
                                              L'0', L"Exit and Continue", NULL,
                                              NULL, NULL, NULL
                                          }, 
                                          {
                                              0, NULL, NULL,
                                              NULL, NULL, NULL
                                          }};

